package cn.lcj.user.service.impl;

import cn.lcj.basic.dto.PhoneCodeDto;
import cn.lcj.basic.utils.SmsUtils;
import cn.lcj.basic.utils.StrUtils;
import cn.lcj.basic.utils.VerifyCodeUtils;
import cn.lcj.user.domain.User;
import cn.lcj.user.mapper.UserMapper;
import cn.lcj.user.service.IVerifyCodeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * $
 *
 * @return $
 * @date $ $
 * @description $
 */
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Override
    public String getImageCode(String key) {
        String code = VerifyCodeUtils.generateVerifyCode(4);
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        return VerifyCodeUtils.verifyCode(115,40,code);
    }

    @Override
    public void getPhoneCode(PhoneCodeDto dto) {
        //一、校验
        //1.校验空值
        if (StringUtils.isEmpty(dto.getImageCodeKey()) || StringUtils.isEmpty(dto.getPhone())) {
            throw new RuntimeException("验证码与手机号不能为空");
        }
        //2.校验手机号是否被注册过(查看数据库里是否保存有信息)
        User user = userMapper.loadByPhone(dto.getPhone());
        if (user != null) {
            throw new RuntimeException("该手机号已经被注册");
        }
        //3.图形验证码是否过期（redis里面获取），是否正确
        Object obj = redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if (obj == null) {
            throw new RuntimeException("图形验证码已经过期，请重新获取");
        }
        //如果用户输入验证码和redis数据库中的验证码不一致
        if (!dto.getImageCode().equalsIgnoreCase(obj.toString())) {
            throw new RuntimeException("图形码输入错误，请重新输入");
        }
        //二、获取短信验证码[业务键（redis中手机短信验证码中的key）：“redister:”+电话号码    值：-手机验证码：时间戳] phoneCodeObj：redis中的短信验证码的key
        //1.通过key从redis获取短信验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("register:" + dto.getPhone());
        //2.判断短信验证码是否为null。phoneCode手机验证码
        String phoneCode = null;
        //2.1为null：第一次发送的手机验证码过期了=》重新生成一个
        if (phoneCodeObj == null) {
            phoneCode = StrUtils.getRandomString(4);
        } else {
            //2.2不为空=手机验证码没过期，判断是否过了重发时间
            long now = System.currentTimeMillis();
            long old = Long.parseLong(phoneCodeObj.toString().split(":")[1]);
            if (old - now > 1 * 60 * 1000) {
                //2.2.2没过了重发时间 抛错误
                throw new RuntimeException("请勿重复请求验证码");
            } else {
                //2.2.2过了重发时间=可以重新发送【通没有过期的那个验证按】
                phoneCode = phoneCodeObj.toString().split(":")[0];
            }
        }
        //3.刷新过期时间=重新添加数据到redis
        redisTemplate.opsForValue().set("register:" + dto.getPhone(), phoneCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);
        //三、调用第三方接口发送短信验证码：调用工具类
        //SmsUtils.sendSms("18166574634","你的手机验证码是"+phoneCode+"请在3分钟内使用");
        System.out.println("你的手机验证码是" + phoneCode + "请在3分钟内使用");

    }

    @Override
    public void getBinderSmsCodeCode(PhoneCodeDto dto) {
        //一、校验
        //1.校验空值
        if (StringUtils.isEmpty(dto.getPhone())) {
            throw new RuntimeException("手机号不能为空");
        }
        //二、获取短信验证码[业务键（redis中手机短信验证码中的key）：“redister:”+电话号码    值：-手机验证码：时间戳] phoneCodeObj：redis中的短信验证码的key
        //1.通过key从redis获取短信验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("binder:" + dto.getPhone());
        //2.判断短信验证码是否为null。phoneCode手机验证码
        String phoneCode = null;
        //2.1为null：第一次发送的手机验证码过期了=》重新生成一个
        if (phoneCodeObj == null) {
            phoneCode = StrUtils.getRandomString(4);
        } else {
            //2.2不为空=手机验证码没过期，判断是否过了重发时间
            long now = System.currentTimeMillis();
            long old = Long.parseLong(phoneCodeObj.toString().split(":")[1]);
            if (old - now > 1 * 60 * 1000) {
                //2.2.2没过了重发时间 抛错误
                throw new RuntimeException("请勿重复请求验证码");
            } else {
                //2.2.2过了重发时间=可以重新发送【通没有过期的那个验证按】
                phoneCode = phoneCodeObj.toString().split(":")[0];
            }
        }
        //3.刷新过期时间=重新添加数据到redis
        redisTemplate.opsForValue().set("binder:" + dto.getPhone(), phoneCode + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);
        //三、调用第三方接口发送短信验证码：调用工具类
        //SmsUtils.sendSms("18166574634","你的手机验证码是"+phoneCode+"请在3分钟内使用");
        System.out.println("你的手机验证码是" + phoneCode + "请在3分钟内使用");

    }
}
